AnsibleでIAM User/Group/Roleを管理する
土日となると天気が悪い北海道の渡辺です。
今日は七夕の創立記念日ということで、AnsibleのAWSモジュールを使ってIAM User, Group, Role を管理する方法を紹介します。
iam / iam_policyモジュール
Ansibleのiamモジュールとiam_policyモジュールはコアモジュールのひとつで、AWS上のIAMリソースとポシリードキュメントを管理します。
IAMリソースは、CloudFormationでも管理可能です。 Ansibleのモジュールを利用した場合、ポリシードキュメントの再利用やテンプレートが利用できる点がポイントとなってきます。
iamモジュールでIAM Roleを作成する
iamモジュールは、iam_type
でIAMリソースの種類を指定し、User / Group / Roleを作成します。
profile
とstate
を指定すること以外で特別なことはありません。
次のplaybookは、developという名前のIAM Roleを作成します。
- hosts: localhost connection: local gather_facts: False vars: profile: default tasks: - name: IAM Role, develop iam: iam_type: role name: develop state: present profile: "{{ profile }}"
iam_type
では、user
, group
, role
のいずれかを指定します。
次のように、with_ite
msなども併用して複数のユーザをまとめて作成することも容易です。
- hosts: localhost connection: local gather_facts: False vars: profile: default tasks: - name: IAM Users iam: iam_type: user name: {{ item }} state: present profile: "{{ profile }}" with_items: - greipel - sagan - kittel - cavendish
iam_policyモジュールでポリシードキュメントを管理する
iam_policyモジュールでは、IAMリソースのポリシードキュメントを管理します。
policy_document
でjsonファイルを指定し、対象のIAMリソースにアタッチします。
次のplaybookは、develop Roleにポリシードキュメントを2つ追加しています。
- hosts: localhost connection: local gather_facts: False vars: profile: default tasks: - name: IAM Policy, develop/cloudwatch-logs iam_policy: iam_type: role iam_name: develop policy_name: cloudwatch-logs policy_document: policy/cloudwatch-logs.json state: present profile: "{{ profile }}" - name: IAM Policy, develop/codedeploy iam_policy: iam_type: role iam_name: develop policy_name: codedeploy policy_document: policy/codedeploy.json state: present profile: "{{ profile }}"
ポリシードキュメントは、playbookを保存したディレクトリにpolicyディレクトリを作成し、それぞれjsonファイルとして保存します。
policy/cloudwatch-logs.json
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:DescribeLogStreams" ], "Resource": [ "arn:aws:logs:*:*:*" ] } ] }
policy/codedeploy.json
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:GetObjectVersion", "s3:ListObjects", "codedeploy:RegisterApplicationRevision" ], "Resource": [ "*" ] } ] }
ポリシードキュメントが独立したファイルとして参照され、共有資産として再利用可能です。
AWSの標準機能で管理ポリシーと呼ばれるテンプレート的なポリシーを提供しています。 現実的な運用では、管理ポリシーでは大雑把過ぎることが多いため、ポリシードキュメントのスニペットをコピペしながら利用することが多いでしょう(主にドキュメントからコピーします)。 Ansibleを利用することで、ポリシードキュメントはチームの資産としてストックできるようになります。
ポリシードキュメントをテンプレート化する
Jinja2によるテンプレート機能はAnsibleの魅力のひとつです。
実は、iam_policyモジュールのpolicy_json
を利用すれば、このテンプレート機能が利用できます。
ポリシードキュメントをテンプレート化し、検証環境と本番環境での差異を吸収できれば、シアワセになれうでしょう。
例えばあるバケットにアクセスできるポリシードキュメントの「バケット名」のみを変数化したポリシードキュメントのテンプレートは次のようになります。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "arn:aws:s3:::{{ s3_bucket_name }}" ] } ] }
しかしながら、Ansible 2.1ではこの機能が利用できません。 テンプレートからの変換時、JSONのエスケープ処理に不具合があるようで、ポリシードキュメント適用時にシンタックスエラーとなってしまいます。 Ansible 2.2では解決されるようなので、この機能は2.2リリース後に紹介したいと思います。
管理ポリシーに対応できない
Ansibleのiam_policyモジュールは管理ポリシーに対応できません。 実はこれ、Ansibleで利用しているbotoが対応していないからというのが理由のようです。
まとめ
AWSでの構成管理と言えば基本はCloudFormationです。 ですが、適用するシーンや再利用性などを検討すると使いにくい部分も幾つかあります。 先日紹介したキーペアの管理やポリシードキュメントあたりはそのひとつです。 AnsibleのAWSモジュールやCloudFormationを併用し、適材適所で構成管理をするのがベストプラクティスではないでしょうか?